package ray.create;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.ArrayList;
import java.util.List;

/**
 * generate service class
 *
 * @author ray
 * @date 2016-03-17 10:34:45
 */
public class MybatisServiceImplPlugin extends PluginAdapter {

    private FullyQualifiedJavaType slf4jLogger;
    private FullyQualifiedJavaType slf4jLoggerFactory;
    private FullyQualifiedJavaType serviceType;
    private FullyQualifiedJavaType daoType;
    private FullyQualifiedJavaType interfaceType;
    private FullyQualifiedJavaType pojoType;
    private FullyQualifiedJavaType pojoCriteriaType;
    private FullyQualifiedJavaType pojoExampleType;

    private FullyQualifiedJavaType autowired;
    private FullyQualifiedJavaType service;

    private String serviceImplPack;
    private String project;
    private String pojoUrl;
    private String servicePack;
    /**
     * 所有的方法
     */
    private List<Method> methods;
    /**
     * 是否添加注解
     */
    private boolean enableAnnotation = true;
    private boolean enableFunction = false;


    public MybatisServiceImplPlugin() {
        super();
        // default is slf4j
        slf4jLogger = new FullyQualifiedJavaType("org.slf4j.Logger");
        slf4jLoggerFactory = new FullyQualifiedJavaType("org.slf4j.LoggerFactory");
        methods = new ArrayList<Method>();
    }

    /**
     * 读取配置文件
     */
    @Override
    public boolean validate(List<String> warnings) {

        String enableAnnotation = properties.getProperty("enableAnnotation");

        String enableFunction = properties.getProperty("enableFunction");


        if (StringUtility.stringHasValue(enableAnnotation)) {
            this.enableAnnotation = StringUtility.isTrue(enableAnnotation);
        }

        if (StringUtility.stringHasValue(enableFunction)) {
            this.enableFunction = StringUtility.isTrue(enableFunction);
        }


        this.servicePack = properties.getProperty("targetPackage");
        this.serviceImplPack = properties.getProperty("implementationPackage");
        this.project = properties.getProperty("targetProject");
        this.pojoUrl = context.getJavaModelGeneratorConfiguration().getTargetPackage();

        if (this.enableAnnotation) {
            autowired = new FullyQualifiedJavaType("javax.annotation.Resource");
            service = new FullyQualifiedJavaType("org.springframework.stereotype.Service");
        }
        return true;
    }

    /**
     *
     */
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> files = new ArrayList<GeneratedJavaFile>();

        String table = introspectedTable.getBaseRecordType();
        String tableName = table.replaceAll(this.pojoUrl + ".", "");
        interfaceType = new FullyQualifiedJavaType(serviceImplPack + "." + tableName + "Service");

        daoType = new FullyQualifiedJavaType(introspectedTable.getMyBatis3JavaMapperType());

        serviceType = new FullyQualifiedJavaType(serviceImplPack + "." + tableName + "ServiceImpl");

        pojoType = new FullyQualifiedJavaType(pojoUrl + "." + tableName);

        pojoExampleType = new FullyQualifiedJavaType(pojoUrl + "." + tableName + "Example");
        pojoCriteriaType = new FullyQualifiedJavaType(pojoUrl + "." + tableName + "Example.Criteria");

        Interface interface1 = new Interface(interfaceType);
        TopLevelClass topLevelClass = new TopLevelClass(serviceType);
        // 导入必须的类
        addImport(interface1, topLevelClass, tableName);
        // 实现类
        addServiceImpl(topLevelClass, introspectedTable, tableName, files);
        addLogger(topLevelClass);

        return files;
    }


    /**
     * add implements class
     *
     * @param introspectedTable
     * @param tableName
     * @param files
     */
    protected void addServiceImpl(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String tableName, List<GeneratedJavaFile> files) {
        topLevelClass.setVisibility(JavaVisibility.PUBLIC);
        topLevelClass.addSuperInterface(interfaceType);
        topLevelClass.setSuperClass("BaseService");

        topLevelClass.addJavaDocLine("/**");
        topLevelClass.addJavaDocLine(" *");
        topLevelClass.addJavaDocLine(" *@author create by Generator ");
        topLevelClass.addJavaDocLine(" **/");
        if (enableAnnotation) {
            topLevelClass.addAnnotation("@Service(\"" + Utils.toLowerCase(interfaceType.getShortName()) + "\")");
            topLevelClass.addImportedType(service);
        }
        // add import dao
        addField(topLevelClass, tableName);
        // add method

        Method method = null;
        if (enableFunction) {
            method = addEntity(introspectedTable, tableName);
            topLevelClass.addMethod(method);

            method = queryEntityById(introspectedTable, tableName);
            topLevelClass.addMethod(method);

            method = updateEntity(introspectedTable, tableName);
            topLevelClass.addMethod(method);


            method = deleteEntity(introspectedTable, tableName);
            topLevelClass.addMethod(method);

            method = pageQueryEntity(introspectedTable, tableName);
            topLevelClass.addMethod(method);


        }
        //此外报错[已修2016-03-22，增加:",context.getJavaFormatter()"]
        GeneratedJavaFile file = new GeneratedJavaFile(topLevelClass, project, context.getJavaFormatter());
        files.add(file);
    }

    private Method addEntity(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/**");
        method.addJavaDocLine(" * 单表新增方法");
        method.addJavaDocLine(" *");
        method.addJavaDocLine(" * @param entity  要新增的对象");
        method.addJavaDocLine(" * @param user 用户信息");
        method.addJavaDocLine(" * @return Result<" + pojoType.getShortName() + "> 新增处理结果对象");
        method.addJavaDocLine(" **/");
        String pk = Utils.underline2Camel(introspectedTable.getPrimaryKeyColumns().get(0).getActualColumnName(), false);
        FullyQualifiedJavaType javaType = new FullyQualifiedJavaType("Result<" + pojoType.getShortName() + ">");
        method.setName("addEntity");
        method.setReturnType(javaType);
        method.addParameter(new Parameter(pojoType, "entity"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType("LoginUser"), "user"));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addAnnotation("@Override");
        method.addAnnotation("@Transactional(rollbackFor = Exception.class)");
        method.addBodyLine("Assert.notNull(entity,\" Class:" + serviceType.getShortName() + ";method:addEntity; Parameter: entity not null\");");
        method.addBodyLine("Assert.notNull(user,\" Class:" + serviceType.getShortName() + ";method:addEntity; Parameter: user not null\");");
        method.addBodyLine("Result<" + pojoType.getShortName() + "> result = new Result<" + pojoType.getShortName() + ">(MsgCodeConstants.SUCCESS,MsgConstants.OP_SUCCESS);");

        method.addBodyLine("entity.setTenantId(user.getTenantId());");
        method.addBodyLine("entity.set" + pk + "(UUIDUtil.getUUID());");
        method.addBodyLine("entity.setIsDelete(DeleteEnum.USE.getValue());");
        method.addBodyLine("this.setUserForAdd(entity, user);");
        method.addBodyLine("int count = " + Utils.toLowerCase(daoType.getShortName()) + ".insertSelective(entity);");
        method.addBodyLine("if(count != 1){");
        method.addBodyLine("  logger.error(\"Class:" + serviceType.getShortName() + ";method:addEntity; is error\");");
        method.addBodyLine("  throw new BussinessException(MsgCodeConstants.ERROR, MsgConstants.INSERT_ERROR);");
        method.addBodyLine("}");
        method.addBodyLine("result.setData(entity);");
        method.addBodyLine("return result;");
        return method;
    }

    /**
     * 查询对象
     *
     * @param introspectedTable
     * @param tableName
     * @return
     */
    private Method queryEntityById(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/**");
        method.addJavaDocLine(" * 单表根据id查询方法");
        method.addJavaDocLine(" *");
        method.addJavaDocLine(" * @param id 主键");
        method.addJavaDocLine(" * @param user 用户信息");
        method.addJavaDocLine(" * @return Result<" + pojoType.getShortName() + "> 查询处理结果对象");
        method.addJavaDocLine(" **/");
        method.setName("queryEntityById");
        method.setReturnType(pojoType);
        method.addParameter(new Parameter(new FullyQualifiedJavaType("String"), "id"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType("LoginUser"), "user"));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addAnnotation("@Override");
        method.addAnnotation("@Transactional(propagation=Propagation.NOT_SUPPORTED,rollbackFor = Exception.class)");
        method.addBodyLine("Assert.notNull(id,\" Class:" + serviceType.getShortName() + ";method:queryEntityById; Parameter: id not null\");");
        method.addBodyLine("return " + Utils.toLowerCase(daoType.getShortName()) + ".selectByPrimaryKey(id);");
        return method;
    }

    /**
     * 更新对象
     *
     * @param introspectedTable
     * @param tableName
     * @return
     */
    private Method updateEntity(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/**");
        method.addJavaDocLine(" * 单表跟新方法");
        method.addJavaDocLine(" *");
        method.addJavaDocLine(" * @param entity  要更新的对象");
        method.addJavaDocLine(" * @param user 用户信息");
        method.addJavaDocLine(" * @return Result<" + pojoType.getShortName() + "> 更新处理结果对象");
        method.addJavaDocLine(" **/");
        FullyQualifiedJavaType javaType = new FullyQualifiedJavaType("Result<" + pojoType.getShortName() + ">");
        method.setName("updateEntity");
        method.setReturnType(javaType);
        method.addParameter(new Parameter(pojoType, "entity"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType("LoginUser"), "user"));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addAnnotation("@Override");
        method.addAnnotation("@Transactional(rollbackFor = Exception.class)");
        method.addBodyLine("Assert.notNull(entity,\" Class:" + serviceType.getShortName() + ";method:updateEntity; Parameter: entity not null\");");
        method.addBodyLine("Assert.notNull(user,\" Class:" + serviceType.getShortName() + ";method:updateEntity; Parameter: user not null\");");
        method.addBodyLine("Result<" + pojoType.getShortName() + "> result = new Result<" + pojoType.getShortName() + ">(MsgCodeConstants.SUCCESS,MsgConstants.OP_SUCCESS);");
        method.addBodyLine("this.setUserForAdd(entity, user);");
        method.addBodyLine("int count = " + Utils.toLowerCase(daoType.getShortName()) + ".updateByPrimaryKeySelective(entity);");
        method.addBodyLine("if(count != 1){");
        method.addBodyLine("  logger.error(\"Class:" + serviceType.getShortName() + ";method:addEntity;  is error\");");
        method.addBodyLine("  throw new BussinessException(MsgCodeConstants.ERROR, MsgConstants.UPDATE_ERROR);");
        method.addBodyLine("}");
        method.addBodyLine("result.setData(entity);");
        method.addBodyLine("return result;");


        return method;
    }

    /**
     * 删除对象
     *
     * @param introspectedTable
     * @param tableName
     * @return
     */
    private Method deleteEntity(IntrospectedTable introspectedTable, String tableName) {
        String pk = Utils.underline2Camel(introspectedTable.getPrimaryKeyColumns().get(0).getActualColumnName(), false);

        Method method = new Method();
        method.addJavaDocLine("/**");
        method.addJavaDocLine(" * 单表删除方法");
        method.addJavaDocLine(" *");
        method.addJavaDocLine(" * @param id  要删除的对象ID");
        method.addJavaDocLine(" * @param user 用户信息");
        method.addJavaDocLine(" * @return Result<" + pojoType.getShortName() + "> 删除处理结果对象");
        method.addJavaDocLine(" **/");

        FullyQualifiedJavaType javaType = new FullyQualifiedJavaType("Result<" + pojoType.getShortName() + ">");
        method.setName("deleteEntity");
        method.setReturnType(javaType);
        method.addParameter(new Parameter(new FullyQualifiedJavaType("String"), "id"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType("LoginUser"), "user"));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addAnnotation("@Override");
        method.addAnnotation("@Transactional(rollbackFor = Exception.class)");
        method.addBodyLine("Assert.notNull(id,\" Class:" + serviceType.getShortName() + ";method:deleteEntity; Parameter: id not null\");");
        method.addBodyLine("Assert.notNull(user,\" Class:" + serviceType.getShortName() + ";method:deleteEntity; Parameter: user not null\");");
        method.addBodyLine("Result<" + pojoType.getShortName() + "> result = new Result<" + pojoType.getShortName() + ">(MsgCodeConstants.SUCCESS,MsgConstants.OP_SUCCESS);");
        method.addBodyLine(pojoType.getShortName() + "  params=new " + pojoType.getShortName() + "(); ");
        method.addBodyLine("params.set" + pk + "(id);");
        method.addBodyLine("params.setIsDelete(DeleteEnum.DELETE.getValue());");
        method.addBodyLine("this.setUserForUpdate(params, user);");
        method.addBodyLine("int count = " + Utils.toLowerCase(daoType.getShortName()) + ".updateByPrimaryKeySelective(params);");
        method.addBodyLine("if(count != 1){");
        method.addBodyLine("  logger.error(\"Class:" + serviceType.getShortName() + ";method:addEntity;  is error\");");
        method.addBodyLine("  throw new BussinessException(MsgCodeConstants.ERROR, MsgConstants.DELETE_ERROR);");
        method.addBodyLine("}");
        method.addBodyLine("result.setData(params);");
        method.addBodyLine("return result;");
        return method;
    }

    /**
     * 删除对象
     *
     * @param introspectedTable
     * @param tableName
     * @return
     */
    private Method pageQueryEntity(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/**");
        method.addJavaDocLine(" * 分页查询");
        method.addJavaDocLine(" *");
        method.addJavaDocLine(" * @param entity  查询对象信息");
        method.addJavaDocLine(" * @param page 分页对象信息");
        method.addJavaDocLine(" * @param user 用户信息");
        method.addJavaDocLine(" * @return PageDTO<" + pojoType.getShortName() + "> 分页查询返回对象");
        method.addJavaDocLine(" **/");
        FullyQualifiedJavaType javaType = new FullyQualifiedJavaType("PageDTO<" + pojoType.getShortName() + ">");
        method.setName("queryEntity");
        method.setReturnType(javaType);
        method.addParameter(new Parameter(pojoType, "entity"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType("PageDTO<" + pojoType.getShortName() + ">"), "page"));
        method.addParameter(new Parameter(new FullyQualifiedJavaType("LoginUser"), "user"));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addAnnotation("@Override");
        method.addAnnotation("@Transactional(propagation=Propagation.NOT_SUPPORTED,rollbackFor = Exception.class)");
        method.addBodyLine("Assert.notNull(entity,\" Class:" + serviceType.getShortName() + ";method:updateEntity; Parameter: entity not null\");");
        method.addBodyLine("Assert.notNull(page,\" Class:" + serviceType.getShortName() + ";method:updateEntity; Parameter: page not null\");");
        method.addBodyLine("Assert.notNull(user,\" Class:" + serviceType.getShortName() + ";method:updateEntity; Parameter: user not null\");");
        method.addBodyLine(pojoType.getShortName() + "Example example = new " + pojoType.getShortName() + "Example();");
        method.addBodyLine("Criteria criteria =  example.createCriteria();");
     /*  method.addBodyLine("if(!user.isSuperManager()){");
        method.addBodyLine("	criteria.andTenantIdEqualTo(user.getTenantId());");
        method.addBodyLine("	criteria.andCreateByUserEqualTo(user.getUserId());");
        method.addBodyLine("}");*/
        method.addBodyLine("//管理员看到自己同租户的数据");
        method.addBodyLine("//管理员看到自己同租户的数据");
        method.addBodyLine("if(user.isManager()){");
        method.addBodyLine(" criteria.andTenantIdEqualTo(user.getTenantId());");
        method.addBodyLine(" } else if(!user.isSuperManager()){");
    	method.addBodyLine(" criteria.andTenantIdEqualTo(user.getTenantId());");
    	method.addBodyLine(" criteria.andCreateByUserEqualTo(user.getUserId());");
    	method.addBodyLine(" } ");
        method.addBodyLine("criteria.andIsDeleteEqualTo(DeleteEnum.USE.getValue());");
        method.addBodyLine("page.setTotal(" + Utils.toLowerCase(daoType.getShortName()) + ".countByExample(example));");
        method.addBodyLine("page.setRecords(" + Utils.toLowerCase(daoType.getShortName()) + ".selectByExample(example));");
        method.addBodyLine("return page;");

        return method;
    }

    /**
     * 添加字段
     *
     * @param topLevelClass
     */
    protected void addField(TopLevelClass topLevelClass, String tableName) {
        Field field = new Field();
        field.setName(Utils.toLowerCase(daoType.getShortName()));
        topLevelClass.addImportedType(daoType);
        field.setType(daoType);
        field.setVisibility(JavaVisibility.PRIVATE);
        if (enableAnnotation) {
            field.addAnnotation("@Resource");
        }
        topLevelClass.addField(field);
    }


    /**
     * type: pojo 1 key 2 example 3 pojo+example 4
     */
    protected String addParams(IntrospectedTable introspectedTable, Method method, int type1) {
        switch (type1) {
            case 1:
                method.addParameter(new Parameter(pojoType, "record"));
                return "record";
            case 2:
                if (introspectedTable.getRules().generatePrimaryKeyClass()) {
                    FullyQualifiedJavaType type = new FullyQualifiedJavaType(introspectedTable.getPrimaryKeyType());
                    method.addParameter(new Parameter(type, "key"));
                } else {
                    for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
                        FullyQualifiedJavaType type = introspectedColumn.getFullyQualifiedJavaType();
                        method.addParameter(new Parameter(type, introspectedColumn.getJavaProperty()));
                    }
                }
                StringBuffer sb = new StringBuffer();
                for (IntrospectedColumn introspectedColumn : introspectedTable.getPrimaryKeyColumns()) {
                    sb.append(introspectedColumn.getJavaProperty());
                    sb.append(",");
                }
                sb.setLength(sb.length() - 1);
                return sb.toString();
            case 3:
                method.addParameter(new Parameter(pojoExampleType, "example"));
                return "example";
            case 4:
                method.addParameter(0, new Parameter(pojoType, "record"));
                method.addParameter(1, new Parameter(pojoExampleType, "example"));
                return "record, example";
            default:
                break;
        }
        return null;
    }

    protected void addComment(JavaElement field, String comment) {
        StringBuilder sb = new StringBuilder();
        field.addJavaDocLine("/**");
        sb.append(" * ");
        comment = comment.replaceAll("\n", "<br>\n\t * ");
        sb.append(comment);
        field.addJavaDocLine(sb.toString());
        field.addJavaDocLine(" */");
    }

    /**
     * add field
     *
     * @param topLevelClass
     */
    protected void addField(TopLevelClass topLevelClass) {
        // add success
        Field field = new Field();
        field.setName("success"); // set var name
        field.setType(FullyQualifiedJavaType.getBooleanPrimitiveInstance()); // type
        field.setVisibility(JavaVisibility.PRIVATE);
        addComment(field, "excute result");
        topLevelClass.addField(field);
        // set result
        field = new Field();
        field.setName("message"); // set result
        field.setType(FullyQualifiedJavaType.getStringInstance()); // type
        field.setVisibility(JavaVisibility.PRIVATE);
        addComment(field, "message result");
        topLevelClass.addField(field);
    }

    /**
     * add method
     */
    protected void addMethod(TopLevelClass topLevelClass) {
        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("setSuccess");
        method.addParameter(new Parameter(FullyQualifiedJavaType.getBooleanPrimitiveInstance(), "success"));
        method.addBodyLine("this.success = success;");
        topLevelClass.addMethod(method);

        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(FullyQualifiedJavaType.getBooleanPrimitiveInstance());
        method.setName("isSuccess");
        method.addBodyLine("return success;");
        topLevelClass.addMethod(method);

        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName("setMessage");
        method.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "message"));
        method.addBodyLine("this.message = message;");
        topLevelClass.addMethod(method);

        method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(FullyQualifiedJavaType.getStringInstance());
        method.setName("getMessage");
        method.addBodyLine("return message;");
        topLevelClass.addMethod(method);
    }

    /**
     * add method
     */
    protected void addMethod(TopLevelClass topLevelClass, String tableName) {
        Method method2 = new Method();
        for (int i = 0; i < methods.size(); i++) {
            Method method = new Method();
            method2 = methods.get(i);
            method = method2;
            method.getBodyLines().clear();
            method.getBodyLines().clear();
            //method.removeAnnotation();
            StringBuilder sb = new StringBuilder();
            sb.append("return this.");
            sb.append(getDaoShort());
            sb.append(method.getName());
            sb.append("(");
            List<Parameter> list = method.getParameters();
            for (int j = 0; j < list.size(); j++) {
                sb.append(list.get(j).getName());
                sb.append(",");
            }
            sb.setLength(sb.length() - 1);
            sb.append(");");
            method.addBodyLine(sb.toString());
            topLevelClass.addMethod(method);
        }
        methods.clear();
    }


    /**
     * import must class
     */
    private void addImport(Interface interfaces, TopLevelClass topLevelClass, String tableName) {
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.function.operator.LoginUser"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.web.Result"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.function.operator.PageDTO"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.web.base.BaseService"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.function.exception.BussinessException"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.function.enums.DeleteEnum"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.util.Assert"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.flyhong.common.util.UUIDUtil"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("org.springframework.transaction.annotation.Propagation"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("org.springframework.transaction.annotation.Transactional"));

        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.iiap.common.MsgConstants"));
        topLevelClass.addImportedType(new FullyQualifiedJavaType("com.zjhc.iiap.common.MsgCodeConstants"));
        topLevelClass.addImportedType(servicePack + "." + tableName + "Service");
        topLevelClass.addImportedType(daoType);
        topLevelClass.addImportedType(interfaceType);
        topLevelClass.addImportedType(pojoType);
        topLevelClass.addImportedType(pojoExampleType);
        topLevelClass.addImportedType(pojoCriteriaType);
        //topLevelClass.addImportedType(listType);
        topLevelClass.addImportedType(slf4jLogger);
        topLevelClass.addImportedType(slf4jLoggerFactory);
        if (enableAnnotation) {
            topLevelClass.addImportedType(service);
            topLevelClass.addImportedType(autowired);
        }
    }

    /**
     * import logger
     */
    private void addLogger(TopLevelClass topLevelClass) {
        Field field = new Field();
        field.setFinal(true);
        field.setInitializationString("LoggerFactory.getLogger(" + topLevelClass.getType().getShortName() + ".class)"); // set value
        field.setName("logger"); // set var name
        field.setStatic(true);
        field.setType(new FullyQualifiedJavaType("Logger")); // type
        field.setVisibility(JavaVisibility.PRIVATE);
        topLevelClass.addField(field);
    }

    private String getDaoShort() {
        return Utils.toLowerCase(daoType.getShortName()) + ".";
    }

}
